# -*- coding:utf-8 -*-
# @FileName : app\api\v1\users\services.py
# @Time     : 2025/11/28
# @Author   : 天空之城
"""用户模块业务逻辑文件

此模块包含用户相关的业务逻辑，处理用户的创建、查询、更新和删除等操作。
"""
from app.models import User, Role, Permission
from app.extensions import db
from app.config import logger


class UserService:
    """用户服务类
    
    提供用户相关的业务逻辑方法，实现用户数据的处理和业务规则的应用。
    """
    
    def get_all_users(self):
        """获取所有用户
        
        Returns:
            用户列表
        """
        return User.query.all()
    
    def get_user_by_id(self, user_id):
        """根据ID获取用户
        
        Args:
            user_id: 用户ID
        
        Returns:
            用户对象或None
        """
        return User.query.get(user_id)
    
    def get_user_by_username(self, username):
        """根据用户名获取用户
        
        Args:
            username: 用户名
        
        Returns:
            用户对象或None
        """
        return User.query.filter_by(username=username).first()
    
    def get_user_by_email(self, email):
        """根据邮箱获取用户
        
        Args:
            email: 邮箱
        
        Returns:
            用户对象或None
        """
        return User.query.filter_by(email=email).first()
    
    def create_user(self, data):
        """创建新用户
        
        Args:
            data: 包含用户信息的字典
        
        Returns:
            新创建的用户对象
        """
        logger.info(f"开始创建用户，用户名: {data['username']}, 邮箱: {data['email']}")
        
        user = User(
            username=data['username'],
            email=data['email']
        )
        # 设置密码（会自动生成哈希值）
        user.password = data['password']
        
        # 保存到数据库
        db.session.add(user)
        db.session.commit()
        
        logger.info(f"用户创建成功，用户ID: {user.id}, 用户名: {user.username}")
        return user
    
    def update_user(self, user_id, data):
        """更新用户信息
        
        Args:
            user_id: 用户ID
            data: 包含更新信息的字典
        
        Returns:
            更新后的用户对象或None
        """
        logger.info(f"开始更新用户信息，用户ID: {user_id}, 更新数据: {data}")
        
        user = self.get_user_by_id(user_id)
        if not user:
            logger.warning(f"用户不存在，更新失败，用户ID: {user_id}")
            return None
        
        # 更新用户信息
        if 'username' in data:
            logger.info(f"更新用户名: {user.username} -> {data['username']}")
            user.username = data['username']
        if 'email' in data:
            logger.info(f"更新邮箱: {user.email} -> {data['email']}")
            user.email = data['email']
        if 'password' in data:
            logger.info("更新用户密码")
            user.password = data['password']
        
        # 保存到数据库
        db.session.commit()
        
        logger.info(f"用户信息更新成功，用户ID: {user.id}, 用户名: {user.username}")
        return user
    
    def delete_user(self, user_id):
        """删除用户
        
        Args:
            user_id: 用户ID
        
        Returns:
            布尔值，表示删除是否成功
        """
        logger.info(f"开始删除用户，用户ID: {user_id}")
        
        user = self.get_user_by_id(user_id)
        if not user:
            logger.warning(f"用户不存在，删除失败，用户ID: {user_id}")
            return False
        
        logger.info(f"删除用户，用户ID: {user.id}, 用户名: {user.username}")
        
        # 从数据库删除
        db.session.delete(user)
        db.session.commit()
        
        logger.info(f"用户删除成功，用户ID: {user_id}")
        return True
    
    def authenticate_user(self, username, password):
        """验证用户身份
        
        Args:
            username: 用户名或邮箱
            password: 密码
        
        Returns:
            用户对象或None
        """
        logger.info(f"开始用户身份验证，用户名/邮箱: {username}")
        
        # 先尝试根据用户名查找用户
        user = self.get_user_by_username(username)
        
        # 如果用户名查找失败，尝试根据邮箱查找用户
        if not user:
            logger.info(f"用户名查找失败，尝试邮箱查找: {username}")
            user = self.get_user_by_email(username)
        
        if not user:
            logger.warning(f"用户不存在: {username}")
            return None
        
        # 验证密码
        if user.verify_password(password):
            logger.info(f"用户验证成功，用户ID: {user.id}, 用户名: {user.username}")
            return user
        else:
            logger.warning(f"密码验证失败，用户ID: {user.id}, 用户名: {user.username}")
            return None
    
    def register_user(self, data):
        """注册新用户
        
        Args:
            data: 包含用户注册信息的字典
        
        Returns:
            新创建的用户对象
        
        Raises:
            ValueError: 当用户名已存在时
        """
        logger.info(f"开始用户注册，请求数据: {data}")
        
        # 检查用户名是否已存在
        if self.get_user_by_username(data['username']):
            logger.warning(f"用户名已存在，注册失败: {data['username']}")
            raise ValueError('用户名已存在')
        
        logger.info(f"创建新用户，用户名: {data['username']}")
        
        user = User(
            username=data['username']
        )
        # 设置密码（会自动生成哈希值）
        user.password = data['password']
        
        # 保存到数据库
        db.session.add(user)
        db.session.commit()
        
        logger.info(f"用户注册成功，用户ID: {user.id}, 用户名: {user.username}")
        return user
    
    def forgot_password(self, email):
        """处理忘记密码请求
        
        Args:
            email: 用户邮箱
        
        Returns:
            布尔值，表示处理是否成功
        
        Note:
            在实际应用中，这里应该发送重置密码邮件
            这里仅作为演示，返回成功结果
        """
        user = self.get_user_by_email(email)
        # 为了安全考虑，即使邮箱不存在也返回成功
        # 实际应用中可以根据需求调整逻辑
        
        if user:
            # 在这里可以添加发送重置密码邮件的逻辑
            print(f"为用户 {user.username} 发送重置密码邮件到 {email}")
        
        return True


class RoleService:
    """角色服务类
    
    提供角色相关的业务逻辑方法。
    """
    
    def get_all_roles(self):
        """获取所有角色
        
        Returns:
            角色列表
        """
        return Role.query.all()
    
    def get_role_by_id(self, role_id):
        """根据ID获取角色
        
        Args:
            role_id: 角色ID
        
        Returns:
            角色对象或None
        """
        return Role.query.get(role_id)
    
    def create_role(self, data):
        """创建新角色
        
        Args:
            data: 包含角色信息的字典
        
        Returns:
            新创建的角色对象
        """
        role = Role(
            name=data['name'],
            description=data.get('description')
        )
        
        db.session.add(role)
        db.session.commit()
        
        return role
    
    def add_permission_to_role(self, role_id, permission_id):
        """为角色添加权限
        
        Args:
            role_id: 角色ID
            permission_id: 权限ID
        
        Returns:
            布尔值，表示添加是否成功
        """
        role = self.get_role_by_id(role_id)
        permission = Permission.query.get(permission_id)
        
        if not role or not permission:
            return False
        
        if permission not in role.permissions:
            role.permissions.append(permission)
            db.session.commit()
        
        return True
    
    def add_role_to_user(self, user_id, role_id):
        """为用户添加角色
        
        Args:
            user_id: 用户ID
            role_id: 角色ID
        
        Returns:
            布尔值，表示添加是否成功
        """
        user = UserService().get_user_by_id(user_id)
        role = self.get_role_by_id(role_id)
        
        if not user or not role:
            return False
        
        if role not in user.roles:
            user.roles.append(role)
            db.session.commit()
        
        return True


class PermissionService:
    """权限服务类
    
    提供权限相关的业务逻辑方法。
    """
    
    def get_all_permissions(self):
        """获取所有权限
        
        Returns:
            权限列表
        """
        return Permission.query.all()
    
    def get_permission_by_id(self, permission_id):
        """根据ID获取权限
        
        Args:
            permission_id: 权限ID
        
        Returns:
            权限对象或None
        """
        return Permission.query.get(permission_id)
    
    def create_permission(self, data):
        """创建新权限
        
        Args:
            data: 包含权限信息的字典
        
        Returns:
            新创建的权限对象
        """
        permission = Permission(
            name=data['name'],
            description=data.get('description')
        )
        
        db.session.add(permission)
        db.session.commit()
        
        return permission
